﻿///-----------------------------------------------------------------------
/// <copyright file="PeriodsAllocationListViewItemViewModel.cs" company="FactSet Research Systems, Inc.">
///     Copyright © FactSet Research Systems, Inc.  All rights reserved 2012.
/// </copyright>
/// <author>Jonathan K. Barez</author>
///-----------------------------------------------------------------------
namespace HousholdISv2.ViewModel.Transaction
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using DataRepository;
    using MVVMCore.ViewModel.Details;
    using MVVMCore;
    using System.Windows;
    using System.Linq;
    using System.Linq.Expressions;
    using GalaSoft.MvvmLight.Messaging;
    using MVVMCore.Messaging;
    using MVVMCore.Interface;

    public class PeriodsAllocationListViewItemViewModel :
        ListViewItemViewModel<PeriodsAllocationListViewViewModel, PeriodAllocation>
    {
        #region Fields

        private static ComboBoxViewModel<ExpenseType> expenseTypes;

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="PeriodsAllocationListViewItemViewModel"/> class.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="data">The data.</param>
        public PeriodsAllocationListViewItemViewModel(PeriodsAllocationListViewViewModel container,
                                                      PeriodAllocation data)
            : base(container, data)
        {
            Messenger.Register<ValidationMessage>(this, this.ProcessMessage);
            var def = this.ExpenseTypes.SelectedItem ?? this.ExpenseTypes.FirstOrDefault();
            this.ExpenseType =
                (from item in this.ExpenseTypes
                 where data.ExpenseTypeId.HasValue && item.Data.Id == data.ExpenseTypeId.Value
                 select item.Description).DefaultIfEmpty(def != null ? def.Data.Description : string.Empty).Single();
            this.CommentText = data.Comment;
            this.Amount = data.Amount.HasValue ? data.Amount.Value : 0M;

            this.ExpenseTypes.SelectionChanged += this.ExpenseTypesSelectionChanged;
        }

        #endregion Constructors

        #region Events

        #endregion Events

        #region Properties

        public Visibility InputVisibility
        {
            get
            {
                return !this.Container.IsReadOnly &&
                       this.IsSelected
                           ? Visibility.Visible
                           : Visibility.Collapsed;
            }
        }

        public Visibility DisplayVisibility
        {
            get
            {
                return !this.Container.IsReadOnly &&
                       this.IsSelected
                           ? Visibility.Collapsed
                           : Visibility.Visible;
            }
        }

        public override bool IsSelected
        {
            get { return base.IsSelected; }

            set
            {
                if (base.IsSelected == value)
                {
                    return;
                }

                base.IsSelected = value;
                this.RaisePropertyChangedEvent(() => this.InputVisibility);
                this.RaisePropertyChangedEvent(() => this.DisplayVisibility);
                this.LoadContext();

                if (this.Container.IsReadOnly)
                {
                    return;
                }

                if (value)
                {
                    this.Container.RefreshACText();
                }
                else
                {
                    this.UpdateContext();
                }
            }
        }

        public ComboBoxViewModel<ExpenseType> ExpenseTypes
        {
            get { return expenseTypes ?? (expenseTypes = InitializeExpenseTypes()); }
            set { expenseTypes = value; }
        }

        public string ExpenseType
        {
            get { return GetValue(() => this.ExpenseType); }
            set { SetValue(() => this.ExpenseType, value); }
        }

        public string CommentText
        {
            get { return GetValue(() => this.CommentText); }
            set { SetValue(() => this.CommentText, value); }
        }

        public decimal Amount
        {
            get { return GetValue(() => this.Amount); }
            set { SetValue(() => this.Amount, value);
                this.Container.UpdateTotal();
            }
        }

        public bool CanBeSaved
        {
            get
            {
                return !string.IsNullOrEmpty(this.ExpenseType) &&
                       !string.IsNullOrEmpty(this.CommentText) &&
                       this.Amount > 0;
            }
        }

        #endregion Properties

        #region Methods

        public void LoadContext()
        {
            var selected = (from item in this.ExpenseTypes
                            where item.Data.Description.Equals(this.ExpenseType, StringComparison.CurrentCulture)
                            select item).SingleOrDefault() ??
                           (this.ExpenseTypes.SelectedItem ?? this.ExpenseTypes.FirstOrDefault());
            if (selected != null &&
                !selected.IsSelected)
            {
                selected.IsSelected = true;
            }

            var notselected = (from item in this.ExpenseTypes
                               where item != selected && item.IsSelected
                               select item);
            notselected.ForEach(item => item.IsSelected = false);
        }

        public void UpdateContext()
        {
            this.ExpenseType = this.ExpenseTypes.SelectedData.Description;
            this.Data.ExpenseTypeId = this.ExpenseTypes.SelectedData.Id;
            Data.Comment = this.CommentText;
            Data.Amount = this.Amount;
        }

        protected override void OnDispose()
        {
            Messenger.Unregister<ValidationMessage>(this, this.ProcessMessage);
            this.ExpenseTypes.SelectionChanged -= this.ExpenseTypesSelectionChanged;
            base.OnDispose();
        }

        private void ProcessMessage(ValidationMessage message)
        {
            // TODO
            ////if (message.Sender == this.Comment)
            ////{
            ////    if (string.IsNullOrWhiteSpace(this.CommentText))
            ////    {
            ////        message.Result = "A comment to briefly describe this allocation is required.";
            ////        return;
            ////    }
            ////}

            ////if (message.Sender == this.Amount)
            ////{
            ////    decimal result;
            ////    if (!decimal.TryParse(this.Amount.Value, out result) || result == 0)
            ////    {
            ////        message.Result = "Please enter a valid number for the amount!";
            ////        return;
            ////    }
            ////}
        }

        private static ComboBoxViewModel<ExpenseType> InitializeExpenseTypes()
        {
            using (var dc = Context.GetContextInstance())
            {
                var cbvm = new ComboBoxViewModel<ExpenseType>();
                dc.ExpenseTypes.ForEach(item => cbvm.Add(item, item.Description));
                return cbvm;
            }
        }

        private void ExpenseTypesSelectionChanged(object sender, SelectionChangedEventArgs<ComboBoxItemViewModel<ExpenseType>> e)
        {
            if (this.Container.IsReadOnly ||
                !this.IsSelected)
            {
                return;
            }

            var data = this.ExpenseTypes.SelectedData;
            if (data == null)
            {
                this.ExpenseType = string.Empty;
            }
            else
            {
                if (!string.Equals(this.ExpenseType, data.Description, StringComparison.InvariantCulture))
                {
                    this.ExpenseType = data.Description;
                }
            }
        }

        #endregion Methods
    }
}
